package frame

import (
	"github.com/dgrijalva/jwt-go"
	"log"
	"reflect"
	"strconv"
	"gitee.com/viwii/vconf/utils"

	"github.com/ant0ine/go-json-rest/rest"
)

// TemplateFunc 模板函数
var TemplateFunc func(int32,rest.ResponseWriter, *rest.Request) error

// BaseHandler 分发模块基本
type BaseHandler struct {
	Path    string
	funcMap map[string]func(int32,rest.ResponseWriter, *rest.Request) error
	AuthMiddleware *JWTMiddleware
}

func (bh *BaseHandler) ServeHTTP(w rest.ResponseWriter, req *rest.Request) {

	funcName := req.PathParam("FuncName")

	var userId int32 = 0
	if (bh.Path != "auth"){
		token, err := bh.AuthMiddleware.parseToken(req)

		// Token should be valid anyway as the RefreshHandler is authed
		if err != nil {
			bh.AuthMiddleware.unauthorized(w)
			log.Println("unauthorized:",err)
			return
		}

		oldClaims := token.Claims.(jwt.MapClaims)

		id,err1 := strconv.Atoi(oldClaims["id"].(string))
		if (err1 != nil){
			log.Println("id error:",err)
			return
		}

		userId = int32(id);
	}



	if callFunc, ok := bh.funcMap[funcName]; ok {
		utils.SafeCall(func(args ...interface{}) error {
			callFunc := args[0].(func(int32,rest.ResponseWriter, *rest.Request)error)
			id := args[1].(*int32)
			w := args[2].(rest.ResponseWriter)
			req := args[3].(*rest.Request)

			err:=callFunc(*id,w,req)
			if (err != nil){
				log.Println("call func:",err)
				return nil
			}


			return nil
		}, callFunc,&userId,w, req)
	} else {
		rest.NotFound(w, req)
	}
}

func (bh *BaseHandler) InitBase(middle *JWTMiddleware,path string,op interface{}){
	bh.AuthMiddleware = middle
	bh.Path = path
	bh.makeFuncMap(op)
}


// MakeFuncMap 处理函数的模块儿映射
func (bh *BaseHandler) makeFuncMap(op interface{}) {
	bh.funcMap = make(map[string]func(int32,rest.ResponseWriter, *rest.Request)error)
	vType := reflect.TypeOf(op)
	vValue := reflect.ValueOf(op)

	for i := 0; i < vType.NumMethod(); i++ {
		methodName := vType.Method(i).Name
		itr := vValue.Method(i).Interface()
		if methodName != "ServeHTTP" && (reflect.TypeOf(itr) == reflect.TypeOf(TemplateFunc)) {
			bh.funcMap[methodName] = itr.(func(int32,rest.ResponseWriter, *rest.Request)error)
		}
	}
}
